<?php

namespace App\Console\Commands;


use Illuminate\Console\Command;
use Modules\Common\Exceptions\Base\OutServiceFaultException;
use Modules\Common\Exceptions\Base\ServerFaultException;
use Modules\Common\Exceptions\Base\UserFaultException;
use Symfony\Component\Finder\Finder;

class GenerateExceptionCode extends Command
{
    protected $signature = 'gen:api-code';
    protected $description = '自动为异常类生成code';

    public function handle()
    {
        $dir = base_path('modules');
        $exceptions = (new Finder())->in($dir)->files();
        $UserFaultExceptionCounts = UserFaultException::API_CODE;
        $ServerFaultExceptionCounts = ServerFaultException::API_CODE;
        $OutServiceFaultExceptionCounts = OutServiceFaultException::API_CODE;
        $userFaultNeedGenerates = [];
        $serverFaultNeedGenerates = [];
        $outServiceFaultNeedGenerates = [];

        foreach ($exceptions as $exception) {
            $contents = file_get_contents($exception->getRealpath());
            $matchExtendsPatten = '/class\s+.+extends\s+(\w+)/';
            if (preg_match($matchExtendsPatten, $contents, $matchExtendResult)) {
                $matchCodePropertyPatten = '/\s+const\s+API_CODE\s*=\s*(\d+)\s*;\s*(?:\n|\r\n)/';
                if ($matchExtendResult[1] === 'UserFaultException') {
                    if (preg_match($matchCodePropertyPatten, $contents, $matchCodePropertyResult)) {
                        $UserFaultExceptionCounts = max($UserFaultExceptionCounts, $matchCodePropertyResult[1]);
                    } else {
                        $userFaultNeedGenerates[] = ['path' => $exception->getRealpath(), 'contents' => $contents];
                    }

                }
                if ($matchExtendResult[1] === 'ServerFaultException') {
                    if (preg_match($matchCodePropertyPatten, $contents, $matchCodePropertyResult)) {
                        $ServerFaultExceptionCounts = max($ServerFaultExceptionCounts, $matchCodePropertyResult[1]);
                    } else {
                        $serverFaultNeedGenerates[] = ['path' => $exception->getRealpath(), 'contents' => $contents];
                    }
                }
                if ($matchExtendResult[1] === 'OutServiceFaultException') {
                    if (preg_match($matchCodePropertyPatten, $contents, $matchCodePropertyResult)) {
                        $OutServiceFaultExceptionCounts = max($OutServiceFaultExceptionCounts, $matchCodePropertyResult[1]);
                    } else {
                        $outServiceFaultNeedGenerates[] = ['path' => $exception->getRealpath(), 'contents' => $contents];
                    }
                }

            }
        }

        foreach ($userFaultNeedGenerates as $needGenerate) {
            $UserFaultExceptionCounts += 10;
            $replaceContents = preg_replace('/class\s+.+\s\{/', '$0' . PHP_EOL . '    const API_CODE=' . $UserFaultExceptionCounts . ';' . PHP_EOL, $needGenerate['contents']);
            file_put_contents($needGenerate['path'], $replaceContents);
            $this->info(sprintf('generate const %s for %s', $UserFaultExceptionCounts, $needGenerate['path']));
        }

        foreach ($serverFaultNeedGenerates as $needGenerate) {
            $ServerFaultExceptionCounts += 10;
            $replaceContents = preg_replace('/class\s+.+\s\{/', '$0' . PHP_EOL . '    const API_CODE=' . $ServerFaultExceptionCounts . ';' . PHP_EOL, $needGenerate['contents']);
            file_put_contents($needGenerate['path'], $replaceContents);
            $this->info(sprintf('generated api_code %s for %s success !', $ServerFaultExceptionCounts, $needGenerate['path']));
        }

        foreach ($outServiceFaultNeedGenerates as $needGenerate) {
            $OutServiceFaultExceptionCounts += 10;
            $replaceContents = preg_replace('/class\s+.+\s\{/', '$0' . PHP_EOL . '    const API_CODE=' . $OutServiceFaultExceptionCounts . ';' . PHP_EOL, $needGenerate['contents']);
            file_put_contents($needGenerate['path'], $replaceContents);
            $this->info(sprintf('generate const %s for %s', $OutServiceFaultExceptionCounts, $needGenerate['path']));
        }
    }


}
